/*
 * Copyright (C) 2006 Johan Maasing johan at zoom.nu Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package nu.zoom.catonine.stylerule;

import java.awt.EventQueue;
import java.util.List;

import javax.swing.DefaultComboBoxModel;

/**
 * A swing list model to display a collection of styling rules.
 * 
 * @author "Johan Maasing" &lt;johan@zoom.nu&gt;
 */
public class StyleRulesListModel extends DefaultComboBoxModel implements StyleRulesManagerListener, StyleRulesListener {

	private static final long serialVersionUID = 1L;
	private List<StyleRules> styleRules;
	private final boolean includeEmptyItem;

	public StyleRulesListModel(final StyleRulesManager manager, final boolean includeEmptyItem) {
		super();
		this.styleRules = manager.getStyleRules();
		manager.addListener(this);
		addMeToListeningToRules();
		this.includeEmptyItem = includeEmptyItem;
	}

	@Override
	public synchronized int getSize() {
		return includeEmptyItem ? styleRules.size() + 1 : styleRules.size();
	}

	@Override
	public synchronized StyleRules getElementAt(final int index) {
		if (includeEmptyItem) {
			if (index == 0) {
				return null;
			} else {
				return styleRules.get(index - 1);
			}
		} else {
			return styleRules.get(index);
		}
	}

	@Override
	public synchronized void styleRulesChanged(StyleRulesManager manager) {
		styleRules = manager.getStyleRules();
		fireIntervalRemoved(this, 0, styleRules.size());
		// Make sure we are registered as listener, remove first if we
		// happen to already be registered.
		removeMeFromListeningToRules();
		addMeToListeningToRules();
		fireIntervalAdded(this, 0, styleRules.size());
	}

	private synchronized void removeMeFromListeningToRules() {
		for (StyleRules rules : styleRules) {
			rules.removeListener(this);
		}
	}

	private synchronized void addMeToListeningToRules() {
		for (StyleRules rules : styleRules) {
			rules.addListener(this);
		}
	}

	@Override
	public void listStructureChanged(StyleRules list) {
		// We only show the list name so we can ignore this.
	}

	@Override
	public void listDataChanged(StyleRules list) {
		// We only show the list name so we can ignore this.
	}

	@Override
	public synchronized void listChangedName(final StyleRules list) {
		final int index = styleRules.indexOf(list);
		if (index != -1) {
			EventQueue.invokeLater(new Runnable() {

				@Override
				public void run() {
					fireContentsChanged(this, index, index);
				}
			});
		}
	}
}
